package com.siwei.mes.job;

import com.siwei.mes.common.util.DateHelper;
import com.siwei.mes.entity.experiment.ExperimentCheckWaybill;
import com.siwei.mes.entity.experiment.ExperimentGenConfig;
import com.siwei.mes.enums.MaterialsEnum;
import com.siwei.mes.mapper.experiment.ExperimentCheckWaybillMapper;
import com.siwei.mes.mapper.experiment.ExperimentGenConfigMapper;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 清空原材料相关  委托有效期
 *
 * @Description: 清空原材料相关  委托有效期
 * @Version: 1.0
 * @author: mlchen
 * @date: 2025/3/14 16:10
 */
@Component
public class ClearMaterialsTimeJob {
    private static final Logger log = LoggerFactory.getLogger("job");
    @Resource
    private ExperimentGenConfigMapper experimentGenConfigMapper;
    @Resource
    private ExperimentCheckWaybillMapper experimentCheckWaybillMapper;


    // 创建一个固定大小的线程池
    private final ExecutorService executorService = Executors.newFixedThreadPool(5);

    /**
     * 每小时清空一次   之前的数据占时不用做兼容了 发布版本的时候直接一次性清清除就行了
     */
    @Scheduled(cron = "0 0 */1 * * ?")
    public void clearJob() {
        List<ExperimentGenConfig> materialsGenConfigList = this.getMaterialsGenConfigList();
        if (materialsGenConfigList.isEmpty()) {
            log.info("按重量生成委托的原材料配置为空，直接跳过");
            return;
        }

        for (ExperimentGenConfig genConfig : materialsGenConfigList) {
            Integer experimentType = genConfig.getExperimentType();
            MaterialsEnum materialsEnum = MaterialsEnum.selectByCode(experimentType);
            if (materialsEnum == null) {
                log.info("未知类型：【{}】", experimentType);
                continue;
            }
            executorService.submit(() -> clearService(materialsEnum, genConfig));
        }
    }

    /**
     * 清理原材料相关绑定数据
     *
     * @param materialsEnum 原材料枚举
     * @param genConfig     原材料生成委托配置
     */
    private void clearService(MaterialsEnum materialsEnum, ExperimentGenConfig genConfig) {
        log.info("开始清理【{}】  委托有效期定时任务！", materialsEnum.getName());

        Integer batchDay = genConfig.getBatchDay();//班次天数 多少天
        String batchTime = genConfig.getBatchTime();//班次时间  到几点
        log.info("班次天数：【{}】，班次时间：【{}】", batchDay, batchTime);
        if (batchDay == null || StringUtils.isBlank(batchTime)) {
            log.info("班次天数或班次时间为空，直接跳过");
            return;
        }
        if (batchDay == 0) {
            log.info("班次天数不允许为0");
            return;
        }
        ExperimentCheckWaybill checkWaybill = new ExperimentCheckWaybill().setCheckType(genConfig.getCheckType())
                .setExperimentType(genConfig.getExperimentType());
        /**这里根据委托为纬度  有时候一个表同一个类型 会有多个试验委托*/
        List<ExperimentCheckWaybill> checkWaybillList = experimentCheckWaybillMapper.getFirstRecord(checkWaybill);

        if (checkWaybillList.isEmpty()) {
            log.info("清空原材料【{}】类型不存在数据", materialsEnum.getName());
            return;
        }

        for (ExperimentCheckWaybill experimentCheckWaybill : checkWaybillList) {
            Date entrustTime = experimentCheckWaybill.getEntrustTime();
            Long experimentId = experimentCheckWaybill.getExperimentId();

            log.info("原材料：【{}】最早委托时间：【{}】，试验委托id：【{}】", materialsEnum.getName(), DateHelper.formatDateTime(entrustTime), experimentId);
            /**这里是拿最开的时间 加上 班次天数*/
            Date lastDate = DateHelper.addDate(entrustTime, Calendar.DATE, batchDay);


            /**这里把时间装换成 yyyy-MM-dd*/
            String dateTime = DateHelper.formatDateTime(lastDate, DateHelper.getDefaultDateFormat(), DateHelper.getDefaultLocal());
            /**添加小时和分钟*/
            String lastBatchTime = dateTime + " " + batchTime + ":00";

            /**判断是不是今天*/
            boolean isToday = DateHelper.isToday(entrustTime);
            if (isToday) {
                log.info("最早的原材料【{}】记录是当天，不清理！", materialsEnum.getName());
                return;
            }

            /**当前时间要大于 最后批次时间*/
            if (new Date().getTime() > DateHelper.parseDateTime(lastBatchTime).getTime()) {
                /**删除这个时间之前的数据*/
                log.info("【{}】符合条件，清空【{}】之前的数据！试验委托id:【{}】", materialsEnum.getName(), lastBatchTime, experimentId);
                log.info("开始清空【experimentCheckWaybill】表数据，清空原材料类型【{}】,检测类型【{}】,试验委托id:【{}】", materialsEnum.getName(), genConfig.getCheckType(), experimentId);

                experimentCheckWaybillMapper.deleteByExperimentId(experimentId);
            } else {
                log.info("不符合条件，不清空【{}】之前的数据！", lastBatchTime);
            }
        }
    }

    /**
     * 获取所有原材料相关配置  按重量的
     *
     * @return
     */
    public List<ExperimentGenConfig> getMaterialsGenConfigList() {
        List<ExperimentGenConfig> newGenConfigList = new ArrayList<>();
        List<ExperimentGenConfig> genConfigList = experimentGenConfigMapper.getList(new ExperimentGenConfig().setIsOpen(1).setCheckRules(2));
        for (ExperimentGenConfig genConfig : genConfigList) {
            /**如果是混凝土类型的 直接过滤掉*/
            if (genConfig.getExperimentType().equals(MaterialsEnum.CONCRETE.getCode())) {
                continue;
            }
            newGenConfigList.add(genConfig);
        }
        return newGenConfigList;
    }
}
